﻿
using MyCrawler.DataService;
using AspNetCore.MyCrawler.DataService;
using AspNetCore.MyCrawler.Model;
using AspNetCore.MyCrawler.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HtmlAgilityPack;



namespace AspNetCore.MyCrawler
{
    public class CrawlerCenter
    {
        private static Logger logger = new Logger(typeof(CrawlerCenter));

        /// <summary>
        /// 抓取
        /// </summary>
        public static void Handler()
        {
            #region MyRegion
            //Console.WriteLine("请输入Y/N进行类别表初始化确认！ Y 删除Tencent_Category表然后重新创建，然后抓取类型数据，N（或者其他）跳过");
            //string input = Console.ReadLine();
            //if (input.Equals("Y", StringComparison.OrdinalIgnoreCase))
            //{
            //    DBInit.InitCategoryTable();
            //    CrawlerCategory();
            //}
            //else
            //{
            //    Console.WriteLine("你选择不初始化类别数据");
            //}
            //Console.WriteLine("*****************^_^**********************");


            //Console.WriteLine("请输入Y/N进行课程数据初始化确认！ Y 删除全部课程数据表然后重新创建，然后抓取课程数据，N（或者其他）跳过");
            //input = Console.ReadLine();
            //if (input.Equals("Y", StringComparison.OrdinalIgnoreCase))
            //{
            //    DBInit.InitTencentSubjectTable();
            //    CrawlerCourse();
            //}
            //Console.WriteLine("*****************^_^**********************");
            #endregion

            #region MyRegion
            CrawlerCategory();
            CrawlerCourse();
            #endregion
        }

        private static void CrawlerCategory()
        {
            Console.WriteLine($"{ DateTime.Now} 腾讯课堂类目开始抓取 - -");
            ISearch search = new CategorySearch();
            search.Crawler();
        }

        /// <summary>
        /// 抓取所有课程 
        /// </summary>
        public static void CrawlerCourse()
        {
            Console.WriteLine($"{ DateTime.Now} 腾讯课堂课程开始抓取 - -");
            //CategoryRepository categoryRepository = new CategoryRepository();
            //先从数据库拿到第三级类目信息
            List<TencentCategoryEntity> categoryList = Constant.CategoryList; //categoryRepository.QueryListByLevel(3);
            var categoryquery = categoryList.Where(a => !a.Name.Contains("全部"));

            //1.有所有的类目
            //2.通过类库抓取所有的类库对应的课程信息

            //多线程   383个类目 难道就开启383个线程吗？
            //既然是通过类库来抓取课程信息，那就每个类目一个线程同时执行；
            //需要控制线程的数量
            //foreach (var category in categoryquery)
            //{
            //    ISearch search =new  CourseSearch(category);
            //    search.Crawler();
            //}

            #region 多线程爬虫    关于多线程   你们还是找一下课堂的助教老师，可以获取一下多线程的内容； 
            //TaskFactory taskFactory = Task.Factory;
            //List<Action> actions = new List<Action>();
            //foreach (TencentCategoryEntity category in categoryquery)
            //{
            //    ISearch searcher = new CourseSearch(category);
            //    actions.Add(new Action(searcher.Crawler));
            //}

            //ParallelOptions options = new ParallelOptions(); //可以控制线程数量
            //options.MaxDegreeOfParallelism = 10; //最多开启10个线程 
            //Parallel.Invoke(options, actions.ToArray()); 
            #endregion

            #region 多线程 爬虫
            //能不能自己封装一个来控制线程呢？
            //col 线程池控制；  不建议这么做；

            TaskFactory taskFactory = new TaskFactory();
            List<Task> taskList = new List<Task>();
            foreach (TencentCategoryEntity category in categoryquery)
            {
                ISearch searcher = new CourseSearch(category);
                taskList.Add( taskFactory.StartNew(searcher.Crawler));
                if (taskList.Count>=10)
                {
                    //等待至少一个线程执行完毕以后  才继续往taskList里面添加Task
                    Task.WaitAny(taskList.ToArray());//等待一堆任务 完成一个任务之后
                    taskList = taskList.Where(t=>!t.IsCanceled  &&! t.IsCompleted &&!t.IsFaulted).ToList();
                }
            }

            Task.WaitAll(taskList.ToArray());
            Console.WriteLine("腾讯课堂的所有课程内容  抓取完毕！");
            #endregion


            Console.WriteLine($"{ DateTime.Now} 腾讯课堂所有课程抓取完毕 - -");
        }

    }
}
